package com.xuecheng.order.listener;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xuecheng.api.order.model.dto.PayResultModel;
import com.xuecheng.common.enums.order.OrderDealStatusEnum;
import com.xuecheng.order.entity.Orders;
import com.xuecheng.order.entity.Pay;
import com.xuecheng.order.service.OrdersService;
import com.xuecheng.order.service.PayService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;

/**
 * Created on 2021/04/18/17:19 周日
 *
 * @author Lantin
 */

@Slf4j
@RocketMQTransactionListener
public class OrderPayTransactionListener implements RocketMQLocalTransactionListener {

    @Autowired
    private OrdersService ordersService;

    @Autowired
    private PayService payService;

    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {

        try {
            PayResultModel payResultModel = getPayResultFromMsg(msg);

            ordersService.paymentStatusSuccess(payResultModel);

            return RocketMQLocalTransactionState.COMMIT;
        } catch (Exception e) {
            return RocketMQLocalTransactionState.ROLLBACK;
        }
    }


    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
        PayResultModel result = getPayResultFromMsg(msg);

        //回查本地方法执行结果
        Long orderId = result.getOrder().getOrderId();

        LambdaQueryWrapper<Orders> ordersWrapper = Wrappers.lambdaQuery();
        ordersWrapper.eq(Orders::getId, orderId)
                .eq(Orders::getStatus, Integer.parseInt(OrderDealStatusEnum.ORDER_DEAL_PAID_STATUS.getCode()));
        int count = ordersService.count(ordersWrapper);
        if (count != 1) {
            return RocketMQLocalTransactionState.ROLLBACK;
        }
        LambdaQueryWrapper<Pay> payWrapper = Wrappers.lambdaQuery();
        payWrapper.eq(Pay::getOrderId, orderId)
                .eq(Pay::getStatus, Pay.PAY_STATUS_PAID);
        int payCount = payService.count(payWrapper);
        if (payCount != 1) {
            return RocketMQLocalTransactionState.ROLLBACK;
        }
        return RocketMQLocalTransactionState.COMMIT;
    }

    private PayResultModel getPayResultFromMsg(Message msg) {
        byte[] payload = (byte[]) msg.getPayload();

        String msgJsonStr = new String(payload);

        return JSON.parseObject(msgJsonStr, PayResultModel.class);
    }
}
